package org.dromara.third.convert.enterprise.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.BusinessServiceException;
import org.dromara.common.core.utils.ValidateUtil;
import org.dromara.system.domain.*;
import org.dromara.system.domain.Process;
import org.dromara.system.mapper.*;
import org.dromara.third.auth.beans.constans.ExceptionEnum;
import org.dromara.third.auth.common.auth.TokenThreadLocal;
import org.dromara.third.auth.util.AESUtil;
import org.dromara.third.convert.enterprise.dto.*;
import org.dromara.third.convert.enterprise.validator.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@RestController
@Slf4j
@RequestMapping("/api/v1")
public class EnterpriseUploadController {

    @Autowired
    private EnterpriseMapper enterpriseMapper;

    @Autowired
    private EnterpriseValidator enterpriseValidator;

    @Autowired
    private RelGeoMapper relGeoMapper;

    @Autowired
    private ProcessMapper processMapper;

    @Autowired
    private ProcessValidator processValidator;

    @Autowired
    private EquipmentInspectionValidator equipmentInspectionValidator;

    @Autowired
    private EquipmentInspectionMapper equipmentInspectionMapper;

    @Autowired
    private EquipmentRepairMapper equipmentRepairMapper;

    @Autowired
    private EquipmentRepairValidator equipmentRepairValidator;

    @Autowired
    private EquipmentMaintenanceValidator equipmentMaintenanceValidator;

    @Autowired
    private EquipmentMaintenanceMapper equipmentMaintenanceMapper;

    @Autowired
    private EquipmentMapper equipmentMapper;

    @Autowired
    private EquipmentValidator equipmentValidator;

    @Autowired
    private DeviceValidator deviceValidator;

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private UserValidator userValidator;

    @Autowired
    private PersonRecordMapper personRecordMapper;

    @Autowired
    private DepartmentMapper departmentMapper;

    @Autowired
    private DepartmentValidator departmentValidator;

    @PostMapping("/enc")
    public R<String> enc(@RequestBody Object o) {
        return R.ok(AESUtil.encrypt(JSONUtil.toJsonStr(o)));
    }

    /**
     * 企业信息
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/enterprise")
    public R<Void> uploadEnterprise(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<EnterpriseFullDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, EnterpriseFullDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, enterpriseValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleEnterpriseData(orgCode, dto);
        return R.ok();
    }

    private void assembleEnterpriseData(String orgCode, List<EnterpriseFullDTO> dtos) {
        dtos.forEach(dto -> {
            try {
                Enterprise enterprise = new Enterprise();
                BeanUtils.copyProperties(dto, enterprise);
                enterprise.setTenantId(orgCode);
                enterpriseMapper.insertOrUpdate(enterprise);
                List<RelGeo> collect = dto.getDqyhj().stream().map(item -> {
                    RelGeo relGeo = new RelGeo();
                    relGeo.setBasicId(enterprise.getId());
                    relGeo.setType(item.getDqyhjDbx());
                    relGeo.setAreaName(item.getDqyhjQymc());
                    relGeo.setGeo(item.getDqyhjWtk());
                    relGeo.setTenantId(orgCode);
                    return relGeo;
                }).collect(Collectors.toList());
                LambdaQueryWrapper<RelGeo> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(RelGeo::getBasicId, enterprise.getId());
                relGeoMapper.delete(queryWrapper);
                relGeoMapper.insertBatch(collect);
            } catch (Exception e) {
                log.error("组装风险分析对象信息异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装风险分析对象信息异常");
            }
        });
    }

    /**
     * 工艺信息
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/list/process")
    public R<Void> uploadProcess(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<ProcessDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, ProcessDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, processValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleProcessData(orgCode, dto);
        return R.ok();
    }

    private void assembleProcessData(String orgCode, List<ProcessDTO> dtos) {
        dtos.forEach(dto -> {
            try {
                Process process = new Process();
                BeanUtils.copyProperties(dto, process);
                process.setTenantId(orgCode);
                processMapper.insertOrUpdate(process);
            } catch (Exception e) {
                log.error("组装工艺信息异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装工艺信息异常");
            }
        });
    }


    /**
     * 部门信息
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/AQ_QYBM")
    public R<Void> uploadAQ_QYBM(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<DepartmentDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, DepartmentDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, departmentValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleDepartmentData(orgCode, dto);
        return R.ok();
    }

    private void assembleDepartmentData(String orgCode, List<DepartmentDTO> dtos) {
        List<Department> departments = dtos.stream().map(dto -> {
            try {
                Department department = new Department();
                BeanUtils.copyProperties(dto, department);
                department.setTenantId(orgCode);
                department.setOrgCode(orgCode);
                return department;
            } catch (Exception e) {
                log.error("组装部门信息异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装部门信息异常");
            }
        }).collect(Collectors.toList());
        departmentMapper.insertOrUpdateBatch(departments);
    }

    /**
     * 人员信息
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/AQ_QYRY")
    public R<Void> uploadAQ_QYRY(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<UserDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, UserDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, userValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleUserData(orgCode, dto);
        return R.ok();
    }

    private void assembleUserData(String orgCode, List<UserDTO> dtos) {
        List<PersonRecord> records = dtos.stream().map(dto -> {
            try {
                PersonRecord personRecord = new PersonRecord();
                BeanUtil.copyProperties(dto, personRecord);
                personRecord.setTenantId(orgCode);
                return personRecord;
            } catch (Exception e) {
                log.error("人员异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装人员信息异常");
            }
        }).collect(Collectors.toList());
        personRecordMapper.insertOrUpdateBatch(records);
    }


    /**
     * 企业生产装置
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/device")
    public R<Void> uploadDevice(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<DeviceDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, DeviceDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, deviceValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleDeviceData(orgCode, dto);
        return R.ok();
    }

    private void assembleDeviceData(String orgCode, List<DeviceDTO> dtos) {
        List<Device> devices = dtos.stream().map(dto -> {
            try {
                Device device = new Device();
                BeanUtil.copyProperties(dto, device);
                device.setTenantId(orgCode);
                return device;
            } catch (Exception e) {
                log.error("生产装置异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装生产装置信息异常");
            }
        }).collect(Collectors.toList());
        deviceMapper.insertOrUpdateBatch(devices);
    }

    /**
     * 企业生产设备
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/deviceEquipment")
    public R<Void> uploadDeviceEquipment(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<EquipmentDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, EquipmentDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, equipmentValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleEquipmentData(orgCode, dto);
        return R.ok();
    }

    private void assembleEquipmentData(String orgCode, List<EquipmentDTO> dtos) {
        List<Equipment> equipments = dtos.stream().map(dto -> {
            try {
                Equipment equipment = new Equipment();
                BeanUtil.copyProperties(dto, equipment);
                equipment.setTenantId(orgCode);
                return equipment;
            } catch (Exception e) {
                log.error("生产设备异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装生产设备信息异常");
            }
        }).collect(Collectors.toList());
        equipmentMapper.insertOrUpdateBatch(equipments);
    }

    /**
     * 设备维护保养
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/AQ_QYSBBY")
    public R<Void> uploadAQ_QYSBBY(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<EquipmentMaintenanceDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, EquipmentMaintenanceDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, equipmentMaintenanceValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleEquipmentMaintenanceData(orgCode, dto);
        return R.ok();
    }

    private void assembleEquipmentMaintenanceData(String orgCode, List<EquipmentMaintenanceDTO> dtos) {
        List<EquipmentMaintenance> maintenances = dtos.stream().map(dto -> {
            try {
                EquipmentMaintenance equipmentMaintenance = new EquipmentMaintenance();
                BeanUtil.copyProperties(dto, equipmentMaintenance);
                equipmentMaintenance.setTenantId(orgCode);
                return equipmentMaintenance;
            } catch (Exception e) {
                log.error("设备维护保养异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装维护保养信息异常");
            }
        }).collect(Collectors.toList());
        equipmentMaintenanceMapper.insertOrUpdateBatch(maintenances);
    }

    /**
     * 设备检维修
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/AQ_QYSBJWX")
    public R<Void> uploadAQ_QYSBJWX(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<EquipmentRepairDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, EquipmentRepairDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, equipmentRepairValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleEquipmentRepairData(orgCode, dto);
        return R.ok();
    }

    private void assembleEquipmentRepairData(String orgCode, List<EquipmentRepairDTO> dtos) {
        List<EquipmentRepair> equipmentRepairList = dtos.stream().map(dto -> {
            try {
                EquipmentRepair equipmentRepair = new EquipmentRepair();
                BeanUtil.copyProperties(dto, equipmentRepair);
                equipmentRepair.setTenantId(orgCode);
                return equipmentRepair;
            } catch (Exception e) {
                log.error("设备检维修异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装检维修信息异常");
            }
        }).collect(Collectors.toList());
        equipmentRepairMapper.insertOrUpdateBatch(equipmentRepairList);
    }

    /**
     * 设备巡查信息
     *
     * @param jsonReq
     * @return
     */
    @PostMapping("/AQ_QYSBXJ")
    public R<Void> uploadAQ_QYSBXJ(@RequestBody String jsonReq) {
        String orgCode = TokenThreadLocal.getThreadLocal();
        List<EquipmentInspectionDTO> dto;
        try {
            String decrypt = AESUtil.decrypt(jsonReq);
            dto = JSONObject.parseArray(decrypt, EquipmentInspectionDTO.class);
        } catch (Exception e) {
            log.error("解析参数异常", e);
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), ExceptionEnum.AuthException06.getMessage());
        }
        // 校验参数
        List<String> errorMessageList = new ArrayList<>();
        ValidateUtil.validate(errorMessageList, dto, equipmentInspectionValidator);
        if (!CollectionUtils.isEmpty(errorMessageList)) {
            String errorMessage = StringUtils.join(errorMessageList, ",");
            throw new BusinessServiceException(ExceptionEnum.AuthException06.getCode(), errorMessage);
        }
        assembleEquipmentInspectionData(orgCode, dto);
        return R.ok();
    }

    private void assembleEquipmentInspectionData(String orgCode, List<EquipmentInspectionDTO> dtos) {
        List<EquipmentInspection> inspections = dtos.stream().map(dto -> {
            try {
                EquipmentInspection equipmentInspection = new EquipmentInspection();
                BeanUtil.copyProperties(dto, equipmentInspection);
                equipmentInspection.setTenantId(orgCode);
                return equipmentInspection;
            } catch (NumberFormatException e) {
                log.error("设备巡查信息异常", e);
                throw new BusinessServiceException(ExceptionEnum.AuthException07.getCode(), "组装工艺信息异常");
            }
        }).collect(Collectors.toList());
        equipmentInspectionMapper.insertOrUpdateBatch(inspections);
    }
}
